<?php


use models\Business\AlibabaProduct;
use models\Business\AlibabaSku;
use models\Business\Order;
use models\Business\Alibaba;
use models\Business\RefundInfo;
use models\Business\System;
use models\Exception\AbstractException;
use Yaf\Registry;

class AlibabaController extends ApiBaseController
{
    /**
     * 1688商品状态变化推送消息接收接口
     * 1688产品下架、1688产品删除、1688产品新增或修改、1688产品上架、1688商品库存变更消息、商品池&超买价变更消息、1688产品审核下架
     * @return bool
     * @throws \Yaf\Exception
     * @throws \models\Exception\Business\AlibabaproductException
     * @throws \models\Exception\DAO\ModelDriverException
     * @throws \models\Exception\DAO\ModelException
     * @throws \models\Exception\DAO\ModelReflectionException
     * @throws \models\Exception\DAO\ModelSqlException
     * @throws \models\Exception\Service\ServiceException
     * @throws \models\Exception\Transformer\TransformerException
     */
    protected function productNotifyAction($data = [])
    {
//        $parameters = Registry::get('parameters');
//        Registry::get('alinotify_order_log')->debug(json_encode($parameters));
//
//        if (!isset($parameters['message']))
//            throw new AbstractException(AbstractException::REQUEST_INVALID, AbstractException::REQUIRED_IS_INVALID_NO);
//
//        $message = json_decode($parameters['message'], true);
//        $data    = isset($message['data']) && !empty($message['data']) ? $message['data'] : [];
//        if (empty($data))
//            throw new AbstractException(AbstractException::REQUEST_INVALID, AbstractException::REQUIRED_IS_INVALID_NO);

        // 修改商品库存
        if (isset($data['OfferInventoryChangeList']) && !empty($data['OfferInventoryChangeList'])) {
            $update_arr = $sku_update_arr = [];
            foreach ($data['OfferInventoryChangeList'] as $product_info) {
                array_push($update_arr, [
                    'product_id'     => $product_info['offerId'],
                    'amount_on_sale' => $product_info['offerOnSale'],
                ]);

                if (isset($product_info['skuId']) && $product_info['skuId'] != 0 &&
                    isset($product_info['skuOnSale']) && $product_info['skuOnSale']) {
                    array_push($sku_update_arr, [
                        'sku_id'         => $product_info['skuId'],
                        'product_id'     => $product_info['offerId'],
                        'amount_on_sale' => $product_info['skuOnSale']
                    ]);
                }
            }

            if (!empty($update_arr)) {
                Registry::get('alinotify_product_log')->info('修改商品数据: ' . json_encode($update_arr));
                AlibabaProduct::collectProduct($update_arr, false);
            }

            if (!empty($sku_update_arr)) {
                Registry::get('alinotify_product_log')->info('修改商品sku数据: ' . json_encode($sku_update_arr));
                AlibabaSku::collectSku($sku_update_arr);
            }

        } else if (isset($data['products']) && !empty($data['products'])) {
            $update_arr = [];
            foreach ($data['products'] as $product_info) {
                if ($product_info['status'] == 'DELETE') {
                    array_push($update_arr, [
                        'product_id'    => $product_info['productId'],
                        'alibaba_stats' => 'deleted',
                        'stats'         => 0,
                    ]);
                }
            }

            if (!empty($update_arr)) {
                AlibabaProduct::collectProduct($update_arr);
                Registry::get('alinotify_product_log')->info('修改商品数据: ' . json_encode($update_arr));
            }

        } // 修改商品状态
        else if (isset($data['status'])) {
            $update_arr['product_id'] = $data['productIds'];
            switch ($data['status']) {
                case 'RELATION_VIEW_PRODUCT_DELETE':
                case 'PRODUCT_DELETE':
                case 'PRODUCT_PRODUCT_DELETE':
                    $update_arr['alibaba_status'] = 'deleted';
                    $update_arr['stats']          = 0;
                    break;
                case 'PRODUCT_EXPIRE':
                case 'RELATION_VIEW_PRODUCT_EXPIRE':
                    $update_arr['alibaba_status'] = 'expired';
                    $update_arr['stats']          = 0;
                    break;
                case 'RELATION_VIEW_PRODUCT_NEW_OR_MODIFY':
                case 'PRODUCT_NEW_OR_MODIFY':
                    $update_arr['alibaba_status'] = 'modified';
                    $update_arr['stats']          = 1;
                    break;
                case 'RELATION_VIEW_PRODUCT_REPOST':
                case 'PRODUCT_REPOST':
                    $update_arr['alibaba_status'] = 'repost';
                    $update_arr['stats']          = 1;
                    break;
                case 'RELATION_VIEW_PRODUCT_AUDIT':
                    $update_arr['alibaba_status'] = 'untread';
                    $update_arr['stats']          = 0;
                    break;
                default:
                    break;
            }
            AlibabaProduct::editProduct($update_arr);
            Registry::get('alinotify_product_log')->info('修改商品数据: ' . json_encode($update_arr));
        }

        return $this->_responseString('success');
    }

    protected function orderNotifyAction($data = [])
    {
        $push  = false;
        $order = Order::getOrderByTradeSn($data['orderId']);
        if (empty($order)) {
            return $this->_responseString('订单不存在');
        }

        // 	1688订单发货（买家视角）
        if ($data['currentStatus'] == 'waitbuyerreceive' && ($order['refund_stats'] == 0 || $order['refund_stats'] == 1) && $order['stats'] == 1) {
            $update_arr = [
                'stats' => 2,
                'sn'    => $order['sn'],
            ];
            if ($order['refund_stats'] == 1)
                $update_arr['refund_stats'] = 0;
            $order_update_res = Order::editOrder($update_arr);
            Registry::get('alinotify_order_log')->info('修改订单数据已发货: ' . json_encode($update_arr) . '。数据修改结果: ' . json_encode($order_update_res));

        } // 1688订单确认收货
        elseif ($data['currentStatus'] == 'confirm_goods_and_has_subsidy' && $order['stats'] == 2) {
            $update_arr = [
                'stats' => 3,
                'sn'    => $order['sn'],
            ];

            $order_update_res = Order::editOrder($update_arr);
            Registry::get('alinotify_order_log')->info('修改订单数据确认收货: ' . json_encode($update_arr) . '。数据修改结果: ' . json_encode($order_update_res));

        }//退款退货
//            elseif ($data['currentStatus'] == 'refundsuccess') {
        //卖家同意退款(退钱)
        elseif ($data['refundAction'] == 'SELLER_AGREE_REFUND' || $data['refundAction'] == 'SYSTEM_AGREE_REFUND') {
            //退款
            //收取服务费
            $order['amount'] -= $order['service_fee'];
            if ($order['refund_stats'] == 1 || $order['refund_stats'] == 5) {
                $update_arr = [
                    'refund_stats' => 3,
                    'sn'           => $order['sn'],
                ];

                $push = true;

                $order_update_res = Order::editOrder($update_arr);
                Registry::get('alinotify_order_log')->info('修改订单数据退款成功: ' . json_encode($update_arr) . '。数据修改结果: ' . json_encode($order_update_res));
                // 退款退运费
                //归还余额给用户
                Order::handleRefund(1, $order);
            }//退货成功，来退款
            elseif ($order['refund_stats'] == 8||$order['refund_stats'] == 9) {
                $update_arr = [
                    'refund_stats' => 4,
                    'sn'           => $order['sn'],
                ];

                $push = true;
                //同意退款，等待买家发货
                $order_update_res = Order::editOrder($update_arr);
                Registry::get('alinotify_order_log')->info('修改订单数据退货成功: ' . json_encode($update_arr) . '。数据修改结果: ' . json_encode($order_update_res));
                //退货扣运费
                $order['amount'] -= $order['fee'];
                //归还余额给用户
                Order::handleRefund(2, $order);
            } else {
                Registry::get('alinotify_order_log')->info('修改订单失败: 退款订单状态错误,参数:' . json_encode($order));
            }
        }//卖家拒绝退款
        elseif ($data['refundAction'] == 'SELLER_REJECT_REFUND') {
            //拒绝退款
            if ($order['refund_stats'] == 1) {
                $update_arr = [
                    'refund_stats' => 5,
                    'sn'           => $order['sn'],
                ];

                $push = true;

                $order_update_res = Order::editOrder($update_arr);
                Registry::get('alinotify_order_log')->info('修改订单数据卖家拒绝退款: ' . json_encode($update_arr) . '。数据修改结果: ' . json_encode($order_update_res));
            }
            //退货中拒绝退款，比如卖家没收到货，商品破损
            if (in_array($order['refund_stats'], [2, 6, 7, 8])) {
                $update_arr = [
                    'refund_stats' => 6,
                    'sn'           => $order['sn'],
                ];

                $push = true;

                $order_update_res = Order::editOrder($update_arr);
                Registry::get('alinotify_order_log')->info('修改订单数据退货中卖家拒绝退款: ' . json_encode($update_arr) . '。数据修改结果: ' . json_encode($order_update_res));
            }
            //记录拒绝理由
//            $refundInfo = RefundInfo::getRefundInfoBySn($data['orderId']);
            $refundInfo = RefundInfo::getRefundInfoByRefundSn($data['refundId']);
            if (empty($refundInfo)) {
                return $this->_responseString('退款信息不存在');
            }
            if ($refundInfo['refund_order_id'] != $data['refundId']) {
                return $this->_responseString('退款订单号出错');
            }
            //查询退款订单详情并记录拒绝理由
            $detail = Alibaba::opQueryOrderRefund($refundInfo['refund_order_id']);
            Registry::get('alinotify_order_log')->info('拒绝退款查询退款订单详情拒绝理由: ' . json_encode($detail));
            $info   = [
                'id'     => $refundInfo['id'],
                'refuse' => isset($detail['opOrderRefundModelDetail']['extInfo']['refuse_reason_txt']) ? $detail['opOrderRefundModelDetail']['extInfo']['refuse_reason_txt'] : '',
            ];
            RefundInfo::editInfo($info);
        }//卖家同意退货（卖家同意退款协议）
        elseif ($data['refundAction'] == 'SELLER_AGREE_REFUND_PROCOTOL') {
            if (in_array($order['refund_stats'], [2, 6])) {
                //获取卖家信息
//                $refundInfo = RefundInfo::getRefundInfoBySn($data['orderId']);
                $refundInfo = RefundInfo::getRefundInfoByRefundSn($data['refundId']);
                if (empty($refundInfo)) {
                    return $this->_responseString('退款信息不存在');
                }
                if ($refundInfo['refund_order_id'] != $data['refundId']) {
                    return $this->_responseString('退款订单号出错');
                }
                //卖家同意退款协议 查询退款订单详情并记录卖家信息
                $detail = Alibaba::opQueryOrderRefund($refundInfo['refund_order_id']);
                Registry::get('alinotify_order_log')->info('查询退款订单详情获取卖家信息: ' . json_encode($detail));
                $info   = [
                    'id'             => $refundInfo['id'],
                    'seller_mobile'  => isset($detail['opOrderRefundModelDetail']['sellerMobile']) ? $detail['opOrderRefundModelDetail']['sellerMobile'] : '',
                    'seller_name'    => isset($detail['opOrderRefundModelDetail']['sellerRealName']) ? $detail['opOrderRefundModelDetail']['sellerRealName'] : '',
                    'seller_address' => isset($detail['opOrderRefundModelDetail']['sellerReceiveAddress']) ? $detail['opOrderRefundModelDetail']['sellerReceiveAddress'] : '',
                ];
                RefundInfo::editInfo($info);
                //修改订单状态
                $update_arr = [
                    'refund_stats' => 7,
                    'sn'           => $order['sn'],
                ];

                $push = true;

                $order_update_res = Order::editOrder($update_arr);

                Registry::get('alinotify_order_log')->info('修改订单数据: ' . json_encode($update_arr) . '。数据修改结果: ' . json_encode($order_update_res));

            } else {
                Registry::get('alinotify_order_log')->info('修改订单失败卖家同意退货: 订单状态错误,参数:' . json_encode($order));
            }
        }//卖家拒绝退货（卖家拒绝退款协议）
        elseif ($data['refundAction'] == 'SELLER_REJECT_REFUND_PROCOTOL') {
            if ($order['refund_stats'] == 2) {
                $update_arr = [
                    'refund_stats' => 6,
                    'sn'           => $order['sn'],
                ];

                $push = true;

                $order_update_res = Order::editOrder($update_arr);
                Registry::get('alinotify_order_log')->info('修改订单数据卖家拒绝退货: ' . json_encode($update_arr) . '。数据修改结果: ' . json_encode($order_update_res));
            }
            //记录拒绝理由
//            $refundInfo = RefundInfo::getRefundInfoBySn($data['orderId']);
            $refundInfo = RefundInfo::getRefundInfoByRefundSn($data['refundId']);
            if (empty($refundInfo)) {
                return $this->_responseString('退款信息不存在');
            }
            if ($refundInfo['refund_order_id'] != $data['refundId']) {
                return $this->_responseString('退款订单号出错');
            }
            //查询退款订单详情并记录拒绝理由
            $detail = Alibaba::opQueryOrderRefund($refundInfo['refund_order_id']);
            Registry::get('alinotify_order_log')->info('拒绝退货协议查询退款订单详情拒绝理由: ' . json_encode($detail));
            $info   = [
                'id'     => $refundInfo['id'],
                'refuse' => isset($detail['opOrderRefundModelDetail']['extInfo']['refuse_reason_txt']) ? $detail['opOrderRefundModelDetail']['extInfo']['refuse_reason_txt'] : '',
            ];
            RefundInfo::editInfo($info);
        } //买家声明发货
        elseif ($data['refundAction'] == 'BUYER_SEND_GOODS' && $order['refund_stats'] == 7) {
            $update_arr = [
                'refund_stats' => 8,
                'sn'           => $order['sn'],
            ];

            $push = true;

            $order_update_res = Order::editOrder($update_arr);
            Registry::get('alinotify_order_log')->info('修改订单数据: ' . json_encode($update_arr) . '。数据修改结果: ' . json_encode($order_update_res));

        } //卖家确认收货
        elseif ($data['refundAction'] == 'SELLER_RECEIVE_GOODS' && $order['refund_stats'] == 8) {
            $update_arr = [
                'refund_stats' => 4,
                'sn'           => $order['sn'],
            ];

            $push = true;

            $order_update_res = Order::editOrder($update_arr);
            Registry::get('alinotify_order_log')->info('修改订单数据: ' . json_encode($update_arr) . '。数据修改结果: ' . json_encode($order_update_res));

        } else {
            Registry::get('alinotify_order_log')->info('修改订单失败:1688参数不再范围内:' . json_encode($order));
        }


//            }

        // 此处根据返回结果进行逻辑判断
        // 如：接收到的参数中，message的currentStatus为waitbuyersend，意为: 1688订单卖家部分发货
        //    接收到的参数中，message的currentStatus为waitbuyerreceive，意为：1688订单发货
        //    接收到的参数中，message的currentStatus为waitBuyerreceive，且存在refundAction时，意为：1688订单售中退款（买家视角）
        // 具体返回结果参见以下链接的"API及消息详细信息"部分
        // https://open.1688.com/solution/solutionDetail.htm?spm=a260s.11247765.je8hk6gy.16.688632baBtdWXZ&solutionKey=1559112028404#apiAndMessageList

        // 推送异步任务客户端
        if ($push === true && isset($order['sn']) && !empty($order['sn'])) {
            $client = new \Task\client();
            try {
                $client->connect();
                $client->sendPush4Order($order['sn']);
            } catch (Exception $e) {
                Registry::get('alinotify_order_log')->err("推送失败,sn: " . $order['sn']);
            } finally {
                $client->close();
            }
        }

        return $this->_responseString('success');


    }

    /**
     * 1688商品状态变化和订单状态变化推送消息接收接口
     */
    public function alibabaNotifyAction()
    {
        $parameters = Registry::get('parameters');
        $message    = json_decode($parameters['message'], true);
        $data       = isset($message['data']) && !empty($message['data']) ? $message['data'] : [];
        if (empty($data))
            throw new AbstractException(AbstractException::REQUEST_INVALID, AbstractException::REQUIRED_IS_INVALID_NO);

        if (isset($data['orderId'])) {
            Registry::get('alinotify_order_log')->info(__METHOD__ . '参数: ' . json_encode($parameters));
            $this->orderNotifyAction($data);
        } else {
            Registry::get('alinotify_product_log')->info(__METHOD__ . '参数: ' . json_encode($parameters));
            $this->productNotifyAction($data);
        }
    }
}
